﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using UnityEngine;

namespace DashFire
{
  class VersionLoader
  {
    public static ResAsyncInfo RequestClientVersion()
    {
      ResAsyncInfo info = new ResAsyncInfo();
      info.CurCoroutine = CoroutineProxy.Instance.StartCoroutine(RequestClientVersionAsync(info));
      return info;
    }
    public static ResAsyncInfo RequestServerVersion()
    {
      ResAsyncInfo info = new ResAsyncInfo();
      info.CurCoroutine = CoroutineProxy.Instance.StartCoroutine(RequestServerVersionAsync(info));
      return info;
    }
    private static IEnumerator RequestClientVersionAsync(ResAsyncInfo info)
    {
      string versionFileStreamingPath = ResLoadHelper.Combine(ResLoadHelper.GetStreamingAssetPath(),
        ResUpdateConfig.s_ResCachePath + ResUpdateConfig.s_ClientVersionFile);
      string versionFilePersistPath = ResLoadHelper.Combine(Application.persistentDataPath,
        ResUpdateConfig.s_ResCachePath + ResUpdateConfig.s_ClientVersionFile);
      bool isPersistFileAlreadyExit = File.Exists(versionFilePersistPath);

      // Read Streaming version file
      ResLoadHelper.Log("RequestClientVersion URL;" + versionFileStreamingPath);
      using (WWW tWWW = new WWW(versionFileStreamingPath)) {
        yield return tWWW;
        try {
          if (tWWW.error != null) {
            ResLoadHelper.Log("RequestClientVersion error");
            info.IsError = true;
            ResUpdateControler.s_UpdateError = ResUpdateError.RequestClientVersion_WWW_Error;
            tWWW.Dispose();
            yield break;
          }
          byte[] bytes = tWWW.bytes;
          if (bytes == null || bytes.Length == 0) {
            ResLoadHelper.Log("RequestClientVersion bytes null or empty data;" + versionFileStreamingPath);
            info.IsError = true;
            ResUpdateControler.s_UpdateError = ResUpdateError.RequestClientVersion_Byte_Error;
            tWWW.Dispose();
            yield break;
          }

          VersionInfo clientVersionInfo = new VersionInfo();
          clientVersionInfo.Load(versionFileStreamingPath, bytes);
          ResUpdateControler.s_BuildinClientVersionInfo = clientVersionInfo;

          ResUpdateControler.s_IsNeedSyncPackage = false;
          if (isPersistFileAlreadyExit) {
            clientVersionInfo = new VersionInfo();
            clientVersionInfo.Load(versionFilePersistPath);
            ResUpdateControler.s_PerszistClientVersionInfo = clientVersionInfo;

            //ulong buildInVersionValue = ResUpdateControler.s_BuildinClientVersionInfo.Version.GetVersionValue();
            //ulong persistVersionValue = ResUpdateControler.s_PerszistClientVersionInfo.Version.GetVersionValue();
            VersionNum buildInVersionNum = ResUpdateControler.s_BuildinClientVersionInfo.Version;
            VersionNum persistVersionNum = ResUpdateControler.s_PerszistClientVersionInfo.Version;
            if (ResUpdateControler.s_BuildinClientVersionInfo.GroupName != ResUpdateControler.s_PerszistClientVersionInfo.GroupName) {
              ResUpdateControler.s_IsNeedSyncPackage = true;
            } else if (buildInVersionNum.GetVersionValue() != persistVersionNum.GetVersionValue()) {
              if (buildInVersionNum.GetAppVersionForceValue() == persistVersionNum.GetAppVersionForceValue()
                && buildInVersionNum.GetResVersionValue() < persistVersionNum.GetResVersionValue()) {
                ResUpdateControler.s_IsNeedSyncPackage = false;
              } else {
                ResUpdateControler.s_IsNeedSyncPackage = true;
              }
            } else {
              ResUpdateControler.s_IsNeedSyncPackage = false;
            }
          } else {
            ResUpdateControler.s_IsNeedSyncPackage = true;
          }

          if (ResUpdateControler.s_IsNeedSyncPackage) {
            string dir = Path.GetDirectoryName(versionFilePersistPath);
            if (!Directory.Exists(dir)) {
              Directory.CreateDirectory(dir);
            }
            if (null != bytes) {
              File.WriteAllBytes(versionFilePersistPath, bytes);
#if UNITY_APPSTORE && UNITY_IPHONE
              iPhone.SetNoBackupFlag(versionFilePersistPath);
#endif
            } else {
              ResLoadHelper.Log("RequestClientVersion bytes null or empty data;" + versionFileStreamingPath);
              info.IsError = true;
              ResUpdateControler.s_UpdateError = ResUpdateError.RequestClientVersion_Byte_Error;
              yield break;
            }
          }

          clientVersionInfo = new VersionInfo();
          clientVersionInfo.Load(versionFilePersistPath);
          ResUpdateControler.s_ClientVersionInfo = clientVersionInfo;
          ResUpdateControler.UpdateVersionInfo();
        } catch (System.Exception ex) {
          ResLoadHelper.Log("RequestClientVersion ex:" + ex);
          info.IsError = true;
          ResUpdateControler.s_UpdateError = ResUpdateError.RequestClientVersion_Load_Error;
          yield break;
        } finally {
          tWWW.Dispose();
        }
      }

      info.IsDone = true;
      info.Progress = 1.0f;
    }
    private static IEnumerator RequestServerVersionAsync(ResAsyncInfo info)
    {
      if (Application.internetReachability == NetworkReachability.NotReachable) {
        ResLoadHelper.Log("RequestServerVersion network not reachable:");
        info.IsError = true;
        ResUpdateControler.s_UpdateError = ResUpdateError.Network_Error;
        yield break;
      }

      string versionFilePersistPath = ResLoadHelper.GetFilePath(ResPathType.Remote, ResUpdateConfig.s_ServerVersionFile);
      string persistVersionFilePath = ResLoadHelper.Combine(Application.persistentDataPath,
        ResUpdateConfig.s_ResCachePath + ResUpdateConfig.s_ServerVersionFile);
      versionFilePersistPath = ResLoadHelper.GetDynamicUrl(versionFilePersistPath);
      ResLoadHelper.Log("RequestServerVersion URL;" + versionFilePersistPath);
      using (WWW tWWW = new WWW(versionFilePersistPath)) {
        yield return tWWW;
        try {
          if (tWWW.error != null || (tWWW.text != null && tWWW.text.ToLower().Contains("<html"))) {
            ResLoadHelper.Log("RequestServerVersion error");
            info.IsError = true;
            ResUpdateControler.s_UpdateError = ResUpdateError.RequestServerVersion_WWW_Error;
            tWWW.Dispose();
            yield break;
          }

          byte[] bytes = tWWW.bytes;
          if (bytes == null || bytes.Length == 0) {
            ResLoadHelper.Log("RequestServerVersion bytes null or empty data;" + ResUpdateConfig.s_ServerVersionFile);
            info.IsError = true;
            ResUpdateControler.s_UpdateError = ResUpdateError.RequestServerVersion_Byte_Error;
            tWWW.Dispose();
            yield break;
          }
          if (!string.IsNullOrEmpty(persistVersionFilePath)) {
            string dir = Path.GetDirectoryName(persistVersionFilePath);
            if (!Directory.Exists(dir)) {
              Directory.CreateDirectory(dir);
            }
            File.WriteAllBytes(persistVersionFilePath, bytes);
#if UNITY_APPSTORE && UNITY_IPHONE
            iPhone.SetNoBackupFlag(persistVersionFilePath);
#endif
          }
        } catch (System.Exception ex) {
          ResLoadHelper.Log("RequestResVersion ex:" + ex);
          info.IsError = true;
          ResUpdateControler.s_UpdateError = ResUpdateError.RequestServerVersion_Save_Error;
          yield break;
        } finally {
          tWWW.Dispose();
        }
      }
      try {
        VersionInfo serverVersionInfo = new VersionInfo();
        serverVersionInfo.Load(persistVersionFilePath);
        ResUpdateControler.s_ServerVersionInfo = serverVersionInfo;
      } catch (System.Exception ex) {
        ResLoadHelper.Log("LoadVersionInfo parse ini ex:" + ex);
        info.IsError = true;
        ResUpdateControler.s_UpdateError = ResUpdateError.RequestServerVersion_Load_Error;
        yield break;
      }
      info.IsDone = true;
      info.Progress = 1.0f;
    }
  }
}
